Utility Maximization and Budget Constraint#
One classic optimization problem in economics that can be solved using optimization methods is the problem of utility maximization subject to a budget constraint. The consumer aims to maximize their utility \(U(x_{1}, x_{2})\). A common form of the utility function is the Cobb-Douglas utility function:
where \(x_{1}\) and \(x_{2}\) are the quantities of two goods consumed, and \(\alpha\) and \(\beta\) are positive constants.
The budget constraint is given by:
where \(p_{1}\) and \(p_{2}\) are the prices of goods 1 and 2, respectively, and \(I\) is the consumer’s income.
So, we can define this optimization problem as:
subject to:
where \(x_{1} \geq 0\) and \(x_{2} \geq 0\).
In this example we define the following parameters:
\(\alpha = 0.5\)
\(\beta = 0.5\)
\(p_{1} = 2\)
\(p_{2} = 5\)
\(I = 10\)
Implementation#
[1]:
import jax.numpy as jnp
alpha = 0.5
beta = 0.5
p1 = 10
p2 = 12
income = 100
def cobb_douglas(x, alpha=alpha, beta=beta):
return x[0] ** alpha * x[1] ** beta
def constraint_function(x, p1=p1, p2=p2, income=income):
return p1 * x[0] + p2 * x[1] - income
[2]:
import matplotlib.pyplot as plt
import numpy as np
# Grid for plotting
x = np.linspace(0.1, 10, 100)
y = np.linspace(0.1, 10, 100)
X, Y = np.meshgrid(x, y)
Z = cobb_douglas((X, Y))
# 3D Plot
fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(121, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis', edgecolor='none')
ax.set_title('Cobb-Douglas Utility Function')
ax.set_xlabel('Good 1 (x1)')
ax.set_ylabel('Good 2 (x2)')
ax.set_zlabel('Utility')
# Contour plot with budget constraint
ax2 = fig.add_subplot(122)
contour = ax2.contour(X, Y, Z, levels=20, cmap='viridis')
ax2.clabel(contour, inline=True, fontsize=8)
ax2.set_title('Contour Plot with Budget Constraint')
ax2.set_xlabel('Good 1 (x1)')
ax2.set_ylabel('Good 2 (x2)')
# Budget constraint line
x_budget = np.linspace(0, income/p1, 100)
y_budget = (income - p1*x_budget) / p2
ax2.plot(x_budget, y_budget, 'r', label='Budget Constraint')
ax2.fill_between(x_budget, 0, y_budget, color='red', alpha=0.1)
ax2.legend()
plt.tight_layout()
plt.show()
[3]:
from optymus import Optimizer
cons_list = [constraint_function]
opt = Optimizer(
f_obj=cobb_douglas,
f_cons=cons_list,
x0=jnp.array([0.5, 0.7]),
method='gradient_descent',
maximize=True,
)
Gradient Descent 0: 37%|███▋ | 37/100 [00:02<00:03, 17.47it/s]
[4]:
opt.print_report()
[4]:
| Method | Initial Guess | Optimal Solution | Objective Function Value | Number of Iterations | Time Elapsed | |
|---|---|---|---|---|---|---|
| Optimization Results | gradient_descent | [0.5, 0.7] | [5.001737523120525, 4.167120580524202] | 4.56539629944386 | 37 | 2.988326 |
[5]:
opt.plot_results(min=0, max=10, show=True, notebook=True)